package com.polytech.web.shared;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import com.polytech.web.client.model.Person;

import fr.inria.acacia.corese.api.IDatatype;
import fr.inria.acacia.corese.exceptions.EngineException;
import fr.inria.edelweiss.kgram.core.Mapping;
import fr.inria.edelweiss.kgram.core.Mappings;
import fr.inria.edelweiss.kgraph.core.Graph;
import fr.inria.edelweiss.kgraph.query.QueryProcess;
import fr.inria.edelweiss.kgraph.rule.RuleEngine;
import fr.inria.edelweiss.kgtool.load.Load;
import fr.inria.edelweiss.kgtool.print.RDFFormat;

public class Query {

	Graph g;
	Load ld;
	QueryProcess exec;
	String query;
	String query1;
	List<Person> amis = new ArrayList<Person>();

	public void init() {
		g = Graph.create(true);
		ld = Load.create(g);
		ld.load("C:/Users/Public/Documents/Master-KIS/WebSem2/FichierProjets/miniProjet.rdfs");
		ld.load("C:/Users/Public/Documents/Master-KIS/WebSem2/FichierProjets/miniProjet.rdf");
		ld.load("C:/Users/Public/Documents/Master-KIS/WebSem2/FichierProjets/miniProjet.rul");
		ld.load("C:/Users/Public/Documents/Master-KIS/WebSem2/FichierProjets/miniProjet2.rul");
		RuleEngine re = ld.getRuleEngine();
		re.process();
		g.addEngine(re);
		g.process();
		exec = QueryProcess.create(g);
	}

	public List<Person> getFriendByCountry(String country, String name) {
		init();
		query = "prefix fb: <http://www.inria.fr/2007/09/11/miniProjet.rdfs#> "
				+ "prefix instance:<http://www.inria.fr/2007/09/11/miniProjet.rdfs-instances#> "
				+ "SELECT (strafter(?x,\"#\") as ?res) ?lastname (strafter(?z,\"#\") as ?country) ?birthDay where {"
				+"?x fb:hasCountry instance:"
				+ country 
				+ "?x foaf:lastName ?lastname "
				+ "?x fb:hasCountry ?z "
				+ "?x foaf:birthday ?birthDay "
				+ " filter(" + "?res != \"" + name + "\" )"
				+ "}";

		try {
			Mappings map = exec.query(query);
			for (Mapping m : map) {
				IDatatype dt = (IDatatype) m.getValue("?res");
				Person person = new Person();
				person.setUsername(dt.getLabel());
				dt = (IDatatype)map.getValue("?lastname");
				person.setUserLastname(dt.getLabel());
				dt = (IDatatype)map.getValue("?country");
				person.setUserCountry(dt.getLabel());
				dt = (IDatatype)map.getValue("?birthDay");
				person.setUserBirthday(dt.getLabel());
				amis.add(person);
			}

		} catch (EngineException e) {
		}

		return amis;

	}

	public List<Person> getAmisEntreprise(String entreprise) {
		init();
		query = "prefix fb: <http://www.inria.fr/2007/09/11/miniProjet.rdfs#>"
				+ "prefix instance:<http://www.inria.fr/2007/09/11/miniProjet.rdfs-instances#>"
				+ "SELECT ((strafter(?x,\"#\") as ?res) ?lastname (strafter(?z,\"#\") as ?country) ?birthDay) where {"
				+ "?x foaf:lastName ?lastname "
				+ "?x fb:hasCountry ?z "
				+ "?x foaf:birthday ?birthDay "
				+"?x fb:hasWorkplace instance:"
				+ entreprise + "}";

		try {
			Mappings map = exec.query(query);
			for (Mapping m : map) {
				IDatatype dt = (IDatatype) m.getValue("?res");
				Person person = new Person();
				person.setUsername(dt.getLabel());
				dt = (IDatatype)map.getValue("?lastname");
				person.setUserLastname(dt.getLabel());
				dt = (IDatatype)map.getValue("?country");
				person.setUserCountry(dt.getLabel());
				dt = (IDatatype)map.getValue("?birthDay");
				person.setUserBirthday(dt.getLabel());
				amis.add(person);
			}

		} catch (EngineException e) {
		}

		return amis;

	}

	public List<Person> getAmisPlageAge(String name , String age1, String age2) {
		init();

		query = "prefix fb: <http://www.inria.fr/2007/09/11/miniProjet.rdfs#> "
				+"prefix foaf: <http://xmlns.com/foaf/0.1/>"
				+ "prefix instance:<http://www.inria.fr/2007/09/11/miniProjet.rdfs-instances#>"
				+ "select distinct (strafter(?x,\"#\") as ?res) ?lastname (strafter(?z,\"#\") as ?country) ?birthDay where{"
				+ "?x rdf:type foaf:Person"
				+ "?x foaf:lastName ?lastname "
				+ "?x fb:hasCountry ?z "
				+ "?x foaf:birthday ?birthDay "
				+ "?x foaf:firstName ?name"
				+ " ?x foaf:age ?age0 filter(xsd:integer(?age0) < "
				+ age1
				+ " &&  xsd:integer(?age0) > " + age2 + " && ?name != \""+name+"\")} ";
		try {
			Mappings map = exec.query(query);
			for (Mapping m : map) {
				IDatatype dt = (IDatatype) m.getValue("?res");
				Person person = new Person();
				person.setUsername(dt.getLabel());
				dt = (IDatatype)map.getValue("?lastname");
				person.setUserLastname(dt.getLabel());
				dt = (IDatatype)map.getValue("?country");
				person.setUserCountry(dt.getLabel());
				dt = (IDatatype)map.getValue("?birthDay");
				person.setUserBirthday(dt.getLabel());
				amis.add(person);
			}

		} catch (EngineException e) {
		}

		return amis;

	}

	public Person findPersonByName(String name, String lastname) {
		init();
		query = "prefix fb: <http://www.inria.fr/2007/09/11/miniProjet.rdfs#> "
				+"prefix foaf: <http://xmlns.com/foaf/0.1/>"
				+ "prefix instance:<http://www.inria.fr/2007/09/11/miniProjet.rdfs-instances#>"
				+ "SELECT (strafter(?x,\"#\") as ?res) ?lastname (strafter(?z,\"#\") as ?country) (strafter(?workplace,\"#\") as ?work) (strafter(?schoolplace,\"#\") as ?school) ?birthDay ?image where {"
				+ "?x foaf:firstName \"" + name + "\" " 
				+ "?x foaf:lastName \"" + lastname + "\" " 
				+ "?x fb:hasCountry ?z "
				+ "?x foaf:birthday ?birthDay "
				+"?x foaf:img ?image "
				+"?x fb:hasWorkplace ?workplace "
				+"?x fb:hasStudiedIn ?schoolplace"
				+ "}";
		try {
			Mappings map = exec.query(query);
			if (map.size() > 0) {
				Person person = new Person ();
				//IDatatype dt = (IDatatype)map.getValue("?lastname");
				//person.setUserLastname(dt.getLabel());
				IDatatype dt = (IDatatype)map.getValue("?country");
				person.setUserCountry(dt.getLabel());
				dt = (IDatatype)map.getValue("?birthDay");
				person.setUserBirthday(dt.getLabel());
				dt = (IDatatype)map.getValue("?image");
				person.setUserImg(dt.getLabel());
				dt = (IDatatype)map.getValue("?work");
				person.setUserWorkPlace(dt.getLabel());
				dt = (IDatatype)map.getValue("?school");
				person.setUserSchool(dt.getLabel());
				return person;
				
			} else {
				return null;
			}
		} catch (EngineException e) {
			e.printStackTrace();
			return null;
		}

	}

	public List<Person> getCountry(String name) {
		init();

		query="prefix fb: <http://www.inria.fr/2007/09/11/miniProjet.rdfs#> "
				+"prefix foaf: <http://xmlns.com/foaf/0.1/>"
				+ "prefix instance:<http://www.inria.fr/2007/09/11/miniProjet.rdfs-instances#>"
				+ "SELECT (strafter(?x,\"#\") as ?res) ?lastname  ?birthDay (strafter(?t,\"#\") as ?samecountry) (strafter(?country,\"#\") as ?countr) where {"
				+ "?x foaf:firstName \"" + name + "\"" + "?x fb:samecountry ?t"
				+" ?t foaf:birthday ?birth" +
				" ?t foaf:lastName ?lastname" +
				" ?t fb:hasCountry ?country"
				+ "}order by ?res";
		
		try {
			Mappings map = exec.query(query);
			for (Mapping m : map) {
				IDatatype dt = (IDatatype) m.getValue("?samecountry");
				IDatatype birth = (IDatatype) m.getValue("?birth");
				IDatatype lastname = (IDatatype) m.getValue("?lastname");
				IDatatype country = (IDatatype) m.getValue("?countr");
				
				Person person = new Person();
				person.setUsername(dt.getLabel());
				person.setUserBirthday(birth.getLabel());
				person.setUserCountry(country.getLabel());
				person.setUserLastname(lastname.getLabel());
				amis.add(person);
			}

		} catch (EngineException e) {
			e.printStackTrace();
			return null;
		}

		return amis;
		}
	

	public String getAge(String name) {
		init();
		query = "prefix fb: <http://www.inria.fr/2007/09/11/miniProjet.rdfs#> "
				+"prefix foaf: <http://xmlns.com/foaf/0.1/>"
				+ "prefix instance:<http://www.inria.fr/2007/09/11/miniProjet.rdfs-instances#>"
				+ "SELECT (strafter(?x,\"#\") as ?res)(?t as ?age) where {"
				+ "?x foaf:firstName \"" + name + "\"" + "?x foaf:age ?t" + "}";
		try {
			Mappings map = exec.query(query);
			for (Mapping m : map) {
				IDatatype dt = (IDatatype) m.getValue("?age");
				return dt.getLabel();

			}
			return "";
		} catch (EngineException e) {
			e.printStackTrace();
			return "";
		}
	}

	public List<Person> getFriends(String name) {
		init();
		query = "prefix fb: <http://www.inria.fr/2007/09/11/miniProjet.rdfs#> "
				+"prefix foaf: <http://xmlns.com/foaf/0.1/>"
				+ "prefix instance:<http://www.inria.fr/2007/09/11/miniProjet.rdfs-instances#>"
				+ "SELECT (strafter(?x,\"#\") as ?res)(strafter(?t,\"#\") as ?friend) (strafter(?country,\"#\") as ?countr) where {"
				+ "?x foaf:firstName \"" + name + "\"" + "?x fb:hasFriend ?t"
				+ " ?t foaf:birthday ?birth" +
				" ?t foaf:lastName ?lastname" 
				//" ?t fb:hasCountry ?country" 
				
				+ "}order by ?res";
		try {
			Mappings map = exec.query(query);
			for (Mapping m : map) {
				IDatatype dt = (IDatatype) m.getValue("?friend");
				IDatatype birth = (IDatatype) m.getValue("?birth");
				IDatatype lastname = (IDatatype) m.getValue("?lastname");
				//IDatatype country = (IDatatype) m.getValue("?countr");
				Person person = new Person();
				person.setUsername(dt.getLabel());
				person.setUserBirthday(birth.getLabel());
				//person.setUserCountry(country.getLabel());
				person.setUserLastname(lastname.getLabel());
				amis.add(person);
			}

		} catch (EngineException e) {
			e.printStackTrace();
			return null;
		}

		return amis;

	}

	
	public List<Person> getFamily(String name) {
		init();
		query = "prefix fb: <http://www.inria.fr/2007/09/11/miniProjet.rdfs#> "
				+"prefix foaf: <http://xmlns.com/foaf/0.1/>"
				+ "prefix instance:<http://www.inria.fr/2007/09/11/miniProjet.rdfs-instances#>"
				+ "SELECT (strafter(?x,\"#\") as ?res)(strafter(?t,\"#\") as ?name)(strafter(?country,\"#\") as ?countr) where {"
				+ "?x foaf:firstName \"" + name + "\"" + "?x fb:hasFamily ?t" +
				" ?t foaf:birthday ?birth" +
				" ?t foaf:lastName ?lastname" +
				" ?t fb:hasCountry ?country"
				
				+ "} order by ?res";
		try {
			Mappings map = exec.query(query);
			for (Mapping m : map) {
				
				IDatatype t = (IDatatype) m.getValue("?name");
				IDatatype birth = (IDatatype) m.getValue("?birth");
				IDatatype lastname = (IDatatype) m.getValue("?lastname");
				IDatatype country = (IDatatype) m.getValue("?countr");
				Person person = new Person();
				person.setUsername(t.getLabel());
				person.setUserBirthday(birth.getLabel());
				person.setUserCountry(country.getLabel());
				person.setUserLastname(lastname.getLabel());
				amis.add(person);
			}

		} catch (EngineException e) {
			e.printStackTrace();
			return null;
		}

		return amis;

	}

	public List<Person> getClassmate(String name) {
		init();
		query = "prefix fb: <http://www.inria.fr/2007/09/11/miniProjet.rdfs#> "
				+"prefix foaf: <http://xmlns.com/foaf/0.1/>"
				+ "prefix instance:<http://www.inria.fr/2007/09/11/miniProjet.rdfs-instances#>"
				+ "SELECT (strafter(?x,\"#\") as ?res)(strafter(?t,\"#\") as ?sameclass) (strafter(?country,\"#\") as ?countr)  where {"
				+ "?x foaf:firstName \"" + name + "\"" + "?x fb:classmate ?t"
				+" ?t foaf:birthday ?birth" +
				" ?t foaf:lastName ?lastname" +
				" ?t fb:hasCountry ?country"
				
				+ "}order by ?res";
		try {
			Mappings map = exec.query(query);
			for (Mapping m : map) {
				IDatatype dt = (IDatatype) m.getValue("?sameclass");
				IDatatype birth = (IDatatype) m.getValue("?birth");
				IDatatype lastname = (IDatatype) m.getValue("?lastname");
				IDatatype country = (IDatatype) m.getValue("?countr");
				
				Person person = new Person();
				person.setUsername(dt.getLabel());
				person.setUserBirthday(birth.getLabel());
				person.setUserCountry(country.getLabel());
				person.setUserLastname(lastname.getLabel());
				
				amis.add(person);
			}
		} catch (EngineException e) {
			e.printStackTrace();
			return null;
		}

		return amis;
	}

	public List<Person> getColleague(String name) {
		init();
	
		query = "prefix fb: <http://www.inria.fr/2007/09/11/miniProjet.rdfs#> "
				+"prefix foaf: <http://xmlns.com/foaf/0.1/>"
				+ "prefix instance:<http://www.inria.fr/2007/09/11/miniProjet.rdfs-instances#>"
				+ "SELECT (strafter(?x,\"#\") as ?res)(strafter(?y,\"#\") as ?colleague) (strafter(?country,\"#\") as ?countr) (strafter(?school,\"#\") as ?schoo) (strafter(?workplace,\"#\") as ?work) where {"
				+ "?x foaf:firstName \"" + name + "\"" + "?x fb:hasWorkplace ?t"
				+" ?y fb:hasWorkplace ?t"
				+" ?y foaf:birthday ?birth" +
				" ?y foaf:lastName ?lastname" +
				" ?y fb:hasCountry ?country"
				+ " filter(?x != ?y)"
				+ "}order by ?res";
		try {
			Mappings map = exec.query(query);
			for (Mapping m : map) {
				IDatatype dt = (IDatatype) m.getValue("?colleague");
				IDatatype birth = (IDatatype) m.getValue("?birth");
				IDatatype lastname = (IDatatype) m.getValue("?lastname");
				IDatatype country = (IDatatype) m.getValue("?countr");
				Person person = new Person();
				person.setUsername(dt.getLabel());
				person.setUserBirthday(birth.getLabel());
				person.setUserCountry(country.getLabel());
				person.setUserLastname(lastname.getLabel());
				
				amis.add(person);
			}

		} catch (EngineException e) {
			e.printStackTrace();
			return null;
		}

		return amis;
	}
	public List<Person> getTopicInterest(String name) {
		init();
		query = "prefix fb: <http://www.inria.fr/2007/09/11/miniProjet.rdfs#> "
				+"prefix foaf: <http://xmlns.com/foaf/0.1/>"
				+ "prefix instance:<http://www.inria.fr/2007/09/11/miniProjet.rdfs-instances#>"
				+ "SELECT (strafter(?x,\"#\") as ?res)(strafter(?t,\"#\") as ?sametopic) (strafter(?country,\"#\") as ?countr)  where {"
				+ "?x foaf:firstName \"" + name + "\"" + "?x fb:sametopicInterest ?t"
				+" ?t foaf:birthday ?birth" +
				" ?t foaf:lastName ?lastname" +
				" ?t fb:hasCountry ?country"
				
				+ "}order by ?res";
		try {
			Mappings map = exec.query(query);
			for (Mapping m : map) {
				IDatatype dt = (IDatatype) m.getValue("?sametopic");
				IDatatype birth = (IDatatype) m.getValue("?birth");
				IDatatype lastname = (IDatatype) m.getValue("?lastname");
				IDatatype country = (IDatatype) m.getValue("?countr");
				
				Person person = new Person();
				person.setUsername(dt.getLabel());
				person.setUserBirthday(birth.getLabel());
				person.setUserCountry(country.getLabel());
				person.setUserLastname(lastname.getLabel());
				
				amis.add(person);
			}

		} catch (EngineException e) {
			e.printStackTrace();
			return null;
		}

		return amis;
	}
	
	public List<Person> getGroupe(String name) {
		init();
		query = "prefix fb: <http://www.inria.fr/2007/09/11/miniProjet.rdfs#> "
				+"prefix foaf: <http://xmlns.com/foaf/0.1/>"
				+ "prefix instance:<http://www.inria.fr/2007/09/11/miniProjet.rdfs-instances#>"
				+ "SELECT (strafter(?x,\"#\") as ?res)(strafter(?t,\"#\") as ?samegroupe) (strafter(?country,\"#\") as ?countr) where {"
				+ "?x foaf:firstName \"" + name + "\"" + "?x fb:samegroupe ?t"
				+" ?t foaf:birthday ?birth" +
				" ?t foaf:lastName ?lastname" +
				" ?t fb:hasCountry ?country"
				
				+ "}order by ?res";
		try {
			Mappings map = exec.query(query);
			for (Mapping m : map) {
				IDatatype dt = (IDatatype) m.getValue("?samegroupe");
				IDatatype birth = (IDatatype) m.getValue("?birth");
				IDatatype lastname = (IDatatype) m.getValue("?lastname");
				IDatatype country = (IDatatype) m.getValue("?countr");
				
				Person person = new Person();
				person.setUsername(dt.getLabel());
				person.setUserBirthday(birth.getLabel());
				person.setUserCountry(country.getLabel());
				person.setUserLastname(lastname.getLabel());
				amis.add(person);
			}

		} catch (EngineException e) {
			e.printStackTrace();
			return null;
		}

		return amis;
	}
	public List<Person> getMailGroupe(String name) {
		init();
		query = "prefix fb: <http://www.inria.fr/2007/09/11/miniProjet.rdfs#> "
				+"prefix foaf: <http://xmlns.com/foaf/0.1/>"
				+ "prefix instance:<http://www.inria.fr/2007/09/11/miniProjet.rdfs-instances#>"
				+ "SELECT (strafter(?x,\"#\") as ?res)(strafter(?t,\"#\") as ?samegroupe) (strafter(?country,\"#\") as ?countr) where {"
				+ "?x foaf:firstName \"" + name + "\"" + "?x fb:samecompte ?t"
				+" ?t foaf:birthday ?birth" +
				" ?t foaf:lastName ?lastname" +
				" ?t fb:hasCountry ?country"
				+ "}order by ?res";
		try {
			Mappings map = exec.query(query);
			for (Mapping m : map) {
				IDatatype dt = (IDatatype) m.getValue("?samecompte");
				IDatatype birth = (IDatatype) m.getValue("?birth");
				IDatatype lastname = (IDatatype) m.getValue("?lastname");
				IDatatype country = (IDatatype) m.getValue("?countr");
				
				Person person = new Person();
				person.setUsername(dt.getLabel());
				person.setUserBirthday(birth.getLabel());
				person.setUserCountry(country.getLabel());
				person.setUserLastname(lastname.getLabel());
				amis.add(person);
			}

		} catch (EngineException e) {
			e.printStackTrace();
			return null;
		}

		return amis;
	}
	public List<Person> getAnniversaire(String name) {
		init();
		query = "prefix fb: <http://www.inria.fr/2007/09/11/miniProjet.rdfs#> "
				+"prefix foaf: <http://xmlns.com/foaf/0.1/>"
				+ "prefix instance:<http://www.inria.fr/2007/09/11/miniProjet.rdfs-instances#>"
				+ "SELECT (strafter(?x,\"#\") as ?res)(strafter(?t,\"#\") as ?datirth) where {"
				+ "?x foaf:firstName \"" + name + "\"" + "?x fb:Amis ?t"
				+ "?t foaf:birthday ?birth "
				+"BIND ( substr(str(?birth), 6,2) AS ?month)"
				+" filter(xsd:integer(?month) = 02)"
				+" BIND ( substr(str(?birth), 6,5) AS ?datebirth)"
				+ "}order by ?res";
		
		try {
			Mappings map = exec.query(query);
			for (Mapping m : map) {
				IDatatype dt = (IDatatype) m.getValue("?datirth");
				Person person = new Person(dt.getLabel());
				amis.add(person);
			}

		} catch (EngineException e) {
			e.printStackTrace();
			return null;
		}

		return amis;
	}

	public Person addFriendSuggestion(String username, String friendname) throws IOException{
			
		//init();
		Graph graph = Graph.create(true);
		 Load ld = Load.create(graph);
		 ld.load("C:/Users/Public/Documents/Master-KIS/WebSem2/FichierProjets/miniProjet.rdf");
		query = "prefix fb: <http://www.inria.fr/2007/09/11/miniProjet.rdfs#> "
				+"prefix foaf: <http://xmlns.com/foaf/0.1/>"
				+ "prefix instance:<http://www.inria.fr/2007/09/11/miniProjet.rdfs-instances#>"
				+"INSERT {"
                +" ?x fb:hasFriend ?t "
                +" ?t fb:hasFriend ?x "
                +"}"
                +"WHERE{"
                +" ?x foaf:firstName \"" + username + "\" "
                +" ?t foaf:firstName \"" + friendname + "\" "
			
				+ "}";
		try {
			 QueryProcess exec = QueryProcess.create(graph);
			  exec.query(query);

			RDFFormat f = RDFFormat.create(graph);
			f.write("C:/Users/Public/Documents/Master-KIS/WebSem2/FichierProjets/miniProjet.rdf");
			System.out.println("??????????????????????????????????????????????????????????????????????????????????");
			System.out.println("??????????????????????????????????????????????????????????????????????????????????");
			System.out.println("??????????????????????????????????????????????????????????????????????????????????");
			//init();
			
			 
				return null;
			
		} catch (EngineException e) {
			e.printStackTrace();
			return null;
		}

	}
}
